package com.xinyi.share.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

/**
 * 
 * @ClassName: RequestUtils
 * @Description: 请求工具类
 * @author wangchuan
 * @date 2014年8月19日 下午12:08:21
 *
 */
public final class RequestUtils {
	private static final Logger logger = Logger.getLogger(RequestUtils.class);
	private final static String GET = "get";
	private final static String POST = "post";

	/**
	 * post请求
	 * 
	 * @param uri
	 * @param params
	 * @param isssl
	 * @return
	 */
	public static String post(String uri, String postbody) {
		return post(uri, null, postbody);
	}

	/**
	 * post请求
	 * 
	 * @param uri
	 * @param params
	 * @param isssl
	 * @return
	 */
	public static String post(String uri, Map<String, String> params) {
		return post(uri, params, null);
	}

	/**
	 * post请求
	 * 
	 * @param uri
	 * @param params
	 * @param isssl
	 * @return
	 */
	public static String post(String uri, Map<String, String> params, String postbody) {
		return requestString(uri, POST, params, postbody);
	}

	/**
	 * GET请求
	 * 
	 * @param uri
	 * @param params
	 * @param isssl
	 * @return
	 */
	public static String get(String uri, Map<String, String> params) {
		return requestString(uri, GET, params, null);
	}

	/**
	 * 
	 * @Title: getStream
	 * @Description: 获取数据流
	 * @param uri
	 * @param params
	 * @return
	 * @return InputStream
	 * @throws
	 */
	public static InputStream getStream(String uri, Map<String, String> params) {
		return requestStream(uri, GET, params, null);
	}

	/**
	 * 发送请求
	 * 
	 * @param uri
	 * @param method
	 * @param params
	 * @param isssl
	 * @return
	 */
	private static String requestString(String uri, String method, Map<String, String> params, String postbody) {
		HttpMethodBase httpMethod = null;
		try {
			if (StringUtils.startsWith(uri, "https")) {
				ProtocolSocketFactory protocolSocketFactory = new SSLProtocolSocketFactory();
				Protocol https = new Protocol("https", protocolSocketFactory, 443);
				Protocol.registerProtocol("https", https);
			}
			HttpClient httpClient = new HttpClient();
			httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
			httpMethod = initMethod(uri, method, params, postbody);
			int statucode = httpClient.executeMethod(httpMethod);
			if (statucode == HttpStatus.SC_OK) {
				return IOUtils.toString(httpMethod.getResponseBodyAsStream(), "UTF-8");
			}
			logger.error("返回状态异常,状态为:" + statucode + "请求地址为:" + uri);
		} catch (UnsupportedEncodingException e) {
			logger.error("请求" + uri + "异常", e);
		} catch (HttpException e) {
			logger.error("请求" + uri + "异常", e);
		} catch (IOException e) {
			logger.error("请求" + uri + "异常", e);
		} finally {
			if (null != httpMethod)
				httpMethod.releaseConnection();
		}
		return null;
	}

	/**
	 * 
	 * @Title: requestStream
	 * @Description: 请求数据并返回stream
	 * @param uri
	 * @param method
	 * @param params
	 * @param postbody
	 * @return
	 * @return InputStream
	 * @throws
	 */
	private static InputStream requestStream(String uri, String method, Map<String, String> params, String postbody) {
		HttpMethodBase httpMethod = null;
		try {
			if (StringUtils.startsWith(uri, "https")) {
				ProtocolSocketFactory protocolSocketFactory = new SSLProtocolSocketFactory();
				Protocol https = new Protocol("https", protocolSocketFactory, 443);
				Protocol.registerProtocol("https", https);
			}
			HttpClient httpClient = new HttpClient();
			httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
			httpMethod = initMethod(uri, method, params, postbody);
			int statucode = httpClient.executeMethod(httpMethod);
			if (statucode == HttpStatus.SC_OK) {
				return httpMethod.getResponseBodyAsStream();
			}
			logger.error("返回状态异常,状态为:" + statucode + "请求地址为:" + uri);
		} catch (UnsupportedEncodingException e) {
			logger.error("请求" + uri + "异常", e);
		} catch (HttpException e) {
			logger.error("请求" + uri + "异常", e);
		} catch (IOException e) {
			logger.error("请求" + uri + "异常", e);
		} finally {
			if (null != httpMethod)
				httpMethod.releaseConnection();
		}
		return null;
	}

	/**
	 * 
	 * @Title: initMethod
	 * @Description: 初始化请求方式
	 * @param uri
	 * @param method
	 * @param params
	 * @param postbody
	 * @return
	 * @throws UnsupportedEncodingException
	 * @return HttpMethodBase
	 * @throws
	 */
	private static HttpMethodBase initMethod(String uri, String method, Map<String, String> params, String postbody) throws UnsupportedEncodingException {
		if (StringUtils.equalsIgnoreCase(GET, method)) {
			return new GetMethod(formatMapToUrl(uri, params));
		} else if (StringUtils.equalsIgnoreCase(POST, method)) {
			PostMethod httpMethod = new PostMethod(formatMapToUrl(uri, params));
			if (null != params && !params.isEmpty()) {
				List<NameValuePair> pairs = new ArrayList<>();
				Iterator<String> it = params.keySet().iterator();
				while (it.hasNext()) {
					String key = it.next();
					pairs.add(new NameValuePair(key, params.get(key)));
				}
				((PostMethod) httpMethod).addParameters(pairs.toArray(new NameValuePair[0]));
			}
			if (StringUtils.isNotEmpty(postbody)) {
				RequestEntity requestEntity = new StringRequestEntity(postbody, null, "utf-8");
				((PostMethod) httpMethod).setRequestEntity(requestEntity);
			}
			return httpMethod;
		}
		return null;
	}

	/**
	 * @throws UnsupportedEncodingException
	 * 
	 * @Title: formatMapToUrl
	 * @Description: URL拼接
	 * @param uri
	 * @param params
	 * @return
	 * @return String
	 * @throws
	 */
	private static String formatMapToUrl(String uri, Map<String, String> params) throws UnsupportedEncodingException {
		StringBuilder urlBuilder = new StringBuilder(uri);
		if (null != params && !params.isEmpty()) {
			urlBuilder.append("?");
			Iterator<String> it = params.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next();
				urlBuilder.append(key).append("=").append(URLEncoder.encode(params.get(key), "UTF-8"));
				if (it.hasNext())
					urlBuilder.append("&");
			}
		}
		return urlBuilder.toString();
	}
}
